home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC_Samples / banner / bannview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  16.5 KB  |  603 lines

  1. // BannerView.cpp : implementation of the CBannerView class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Banner.h"
  6. #include "Metrics.h"
  7. #include "BannDoc.h"
  8. #include "BannView.h"
  9. #include "MainFrm.h"
  10.  
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16.  
  17.  
  18.  
  19. int CBannerView::s_nRulerTickSize = 10;
  20. int CBannerView::s_nRulerNumberSize = 20; // just used for the rect, not the numbers.
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CBannerView
  24.  
  25. IMPLEMENT_DYNCREATE(CBannerView, CScrollView)
  26.  
  27. BEGIN_MESSAGE_MAP(CBannerView, CScrollView)
  28.     //{{AFX_MSG_MAP(CBannerView)
  29.     ON_COMMAND(ID_BANNER_TEXT, OnBannerText)
  30.     ON_COMMAND(ID_PAGES, OnPageBreaks)
  31.     ON_COMMAND(ID_RULER, OnRuler)
  32.     ON_UPDATE_COMMAND_UI(ID_RULER, OnUpdateRuler)
  33.     ON_UPDATE_COMMAND_UI(ID_PAGE_BREAKS, OnUpdatePageBreaks)
  34.     ON_WM_CREATE()
  35.     ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
  36.     ON_WM_ERASEBKGND()
  37.     ON_WM_KEYDOWN()
  38.     //}}AFX_MSG_MAP
  39. END_MESSAGE_MAP()
  40.  
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CBannerView construction/destruction
  43.  
  44. CBannerView::CBannerView() 
  45. {
  46.     m_bRuler      = TRUE;
  47.     m_bPageBreaks = TRUE;
  48.     m_nCurrZoom   = CBannerMetrics::DefaultZoom();
  49.     m_fontScreen.m_hObject  = NULL;
  50.     m_fontPrinter.m_hObject = NULL;
  51.     m_rcMarginsPrintDlg = CRect(1250,1000,1250,1000); // 1000ths of inches
  52. }
  53.  
  54. CBannerView::~CBannerView()
  55. {
  56.     if(m_fontScreen.m_hObject != NULL)
  57.         m_fontScreen.DeleteObject();
  58. }
  59.  
  60.  
  61.  
  62.  
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CBannerView diagnostics
  65.  
  66. #ifdef _DEBUG
  67. void CBannerView::AssertValid() const
  68. {
  69.     CScrollView::AssertValid();
  70. }
  71.  
  72. void CBannerView::Dump(CDumpContext& dc) const
  73. {
  74.     CScrollView::Dump(dc);
  75. }
  76.  
  77. CBannerDoc* CBannerView::GetDocument() // non-debug version is inline
  78. {
  79.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBannerDoc)));
  80.     return (CBannerDoc*)m_pDocument;
  81. }
  82. #endif //_DEBUG
  83.  
  84. /////////////////////////////////////////////////////////////////////////////
  85. // CBannerView message handlers
  86.  
  87. void CBannerView::ComputeSizes(CDC *pPrinterDC /* = NULL */)
  88. {
  89.     CDC PrinterDC; 
  90.     CDC *pScreenDC = GetDC();
  91.     BOOL bDeleteTempPrinterDC = FALSE;
  92.  
  93.     // Query the printer page size (use defaults if no printer is available)
  94.     // Note: it is not possible to get the margins at this point... we have to use
  95.     // the cached copy (m_rcMarginsPrintDlg).
  96.     CPrintDialog printDlg(FALSE);
  97.     printDlg.GetDefaults();
  98.     if(printDlg.m_pd.hdc == NULL)
  99.     {
  100.         // No printer detected, so use default information built into CBannerMetrics
  101.         pPrinterDC = pScreenDC;
  102.         m_sizePagePrinter = CSize(0,0);
  103.     }
  104.     else
  105.     {
  106.         // Printer detected, update mxPrinter with the default information
  107.         bDeleteTempPrinterDC = TRUE;
  108.         pPrinterDC = &PrinterDC;
  109.         pPrinterDC->Attach(printDlg.m_pd.hdc);
  110.         m_sizePagePrinter = CSize(pPrinterDC->GetDeviceCaps(HORZRES),
  111.                                   pPrinterDC->GetDeviceCaps(VERTRES));
  112.     }
  113.  
  114.     // Get the printer metrics
  115.     CBannerMetrics mxPrinter(pPrinterDC);
  116.  
  117.     // Come up with defaults for m_sizePagePrinter if we need to
  118.     if((m_sizePagePrinter.cx == 0) || (m_sizePagePrinter.cy == 0))
  119.     {
  120.         m_sizePagePrinter.cx = 10500 * mxPrinter.Inch().cx / 1000;
  121.         m_sizePagePrinter.cy =  8000 * mxPrinter.Inch().cy / 1000;
  122.     }
  123.  
  124.     // Convert margins from 1000th" to pixels
  125.     m_rcMarginsPrinter = ScaleSize(m_rcMarginsPrintDlg, mxPrinter.Inch(), CSize(1000,1000));
  126.  
  127.     // Get size of view for the printer (large!), add in margins, and round up page-wise
  128.     m_sizeTextPrinter = GetTextSize(pPrinterDC);
  129.     if((m_sizeTextPrinter.cx == 0) || (m_sizeTextPrinter.cy == 0))
  130.         m_sizeViewPrinter = m_sizePagePrinter;
  131.     else
  132.     {
  133.         m_sizeViewPrinter = m_sizeTextPrinter;
  134.         m_sizeViewPrinter.cx += m_rcMarginsPrinter.left + m_rcMarginsPrinter.right;
  135.         m_sizeViewPrinter.cy += m_rcMarginsPrinter.top  + m_rcMarginsPrinter.bottom;
  136.         m_sizeViewPrinter.cx += m_sizePagePrinter.cx - (m_sizeViewPrinter.cx % m_sizePagePrinter.cx);
  137.         m_sizeViewPrinter.cy += m_sizePagePrinter.cy - (m_sizeViewPrinter.cy % m_sizePagePrinter.cy);
  138.     }
  139.  
  140.     // Calculate page size count
  141.     m_sizePageCount.cx = m_sizeViewPrinter.cx / m_sizePagePrinter.cx;
  142.     m_sizePageCount.cy = m_sizeViewPrinter.cy / m_sizePagePrinter.cy;
  143.  
  144.     // Derive metrics for the screen
  145.     CBannerMetrics mxScreen(pScreenDC, m_nCurrZoom);
  146.     m_sizeTextScreen  = GetTextSize(pScreenDC, m_nCurrZoom);
  147.     m_sizePageScreen  = ScaleSize(m_sizePagePrinter,  mxScreen.Inch(), mxPrinter.Inch());
  148.     m_sizeViewScreen  = ScaleSize(m_sizeViewPrinter,  mxScreen.Inch(), mxPrinter.Inch());
  149.     m_rcMarginsScreen = ScaleSize(m_rcMarginsPrinter, mxScreen.Inch(), mxPrinter.Inch());
  150.  
  151.     // Delete the temporary printer DC from the print dialog
  152.     if(bDeleteTempPrinterDC)
  153.         pPrinterDC->DeleteDC();
  154. }
  155.  
  156.  
  157.  
  158. void CBannerView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
  159. {
  160.     CWaitCursor* pWait = new CWaitCursor;
  161.     
  162.     ComputeSizes();
  163.  
  164.     CRect rcWnd;
  165.     GetClientRect(&rcWnd);
  166.     CSize sizeScrollPage(m_sizeViewScreen.cx/m_sizePageCount.cx,
  167.                          m_sizeViewScreen.cy/m_sizePageCount.cy);
  168.     CSize sizeScrollLine(rcWnd.Width()/10, rcWnd.Height()/6);
  169.     SetScrollSizes(MM_TEXT,m_sizeViewScreen,sizeScrollPage,sizeScrollLine);
  170.  
  171.     if(m_fontScreen.m_hObject != NULL)
  172.         m_fontScreen.DeleteObject();
  173.  
  174.     BOOL bResult = CreateBannerFont(GetDC(), &m_fontScreen, m_nCurrZoom);
  175.  
  176.     InvalidateRect(NULL);
  177.  
  178.     delete pWait;
  179.  
  180.     if(!bResult)
  181.     {
  182.         if(m_nCurrZoom == 0)
  183.         {
  184.             AfxMessageBox(CString((LPCTSTR)IDS_MESSAGE1));
  185.             ::PostQuitMessage(0);
  186.         }
  187.         else
  188.         {
  189.             AfxMessageBox(CString((LPCTSTR)IDS_MESSAGE2));
  190.             m_nCurrZoom--;
  191.             CMainFrame *pFrame = (CMainFrame *)GetParentFrame();
  192.             if(pFrame != NULL)
  193.                 pFrame->m_wndZoomList.SetCurSel(m_nCurrZoom);
  194.             GetDocument()->UpdateAllViews(NULL);
  195.         }
  196.     }                
  197. }
  198.  
  199.  
  200. /////////////////////////////////////////////////////////////////////////////
  201. // CBannerView drawing
  202.  
  203. BOOL CBannerView::OnEraseBkgnd(CDC* pDC) 
  204. {
  205.     CPen pen, *pPrevPen;
  206.     pen.CreateStockObject(NULL_PEN);
  207.     pPrevPen = pDC->SelectObject(&pen);
  208.  
  209.     CBrush brush, *pPrevBrush;
  210.     brush.CreateStockObject(WHITE_BRUSH);
  211.     pPrevBrush = pDC->SelectObject(&brush);
  212.  
  213.     CRect rect;
  214.     GetClientRect(&rect);
  215.     rect.InflateRect(1,1);
  216.     pDC->Rectangle(&rect);
  217.  
  218.     pDC->SelectObject(pPrevPen);
  219.     pen.DeleteObject();
  220.  
  221.     pDC->SelectObject(pPrevBrush);
  222.     brush.DeleteObject();
  223.  
  224.     return TRUE;
  225. }
  226.  
  227. void CBannerView::OnDraw(CDC* pDC)
  228. {
  229.     CSize scroll(-GetDeviceScrollPosition().x, -GetDeviceScrollPosition().y);
  230.     CBannerMetrics mx(pDC, m_nCurrZoom);
  231.  
  232.     pDC->SetBkMode(TRANSPARENT);
  233.  
  234.     if(m_bPageBreaks)
  235.         DrawPageBreaks(pDC, scroll, mx);
  236.  
  237.     if(m_fontScreen.m_hObject != NULL)
  238.         DrawBanner(pDC, scroll, mx);
  239.  
  240.     if(m_bRuler && (mx.ZoomFrac(m_nCurrZoom) >= .24))
  241.         DrawRuler(pDC, scroll, mx);
  242. }
  243.  
  244.  
  245. void CBannerView::DrawBanner(CDC *pDC, CSize& scroll, CBannerMetrics& mx)
  246. {
  247.     CSize& sizeView  = pDC->IsPrinting() ? m_sizeViewPrinter  : m_sizeViewScreen;
  248.     CSize& sizeText  = pDC->IsPrinting() ? m_sizeTextPrinter  : m_sizeTextScreen;
  249.     CRect& rcMargins = pDC->IsPrinting() ? m_rcMarginsPrinter : m_rcMarginsScreen; 
  250.  
  251.     CRect rcText(0, 0, sizeText.cx, sizeText.cy);
  252.  
  253.     if(GetCenterH())
  254.         rcText.OffsetRect((sizeView.cx-sizeText.cx)/2, 0);
  255.     else
  256.         rcText.OffsetRect(rcMargins.left, 0);
  257.  
  258.     if(GetCenterV())
  259.         rcText.OffsetRect(0, (sizeView.cy-sizeText.cy)/2);
  260.     else
  261.         rcText.OffsetRect(0, rcMargins.top);
  262.  
  263.     if(GetBorder())
  264.         rcText.OffsetRect(mx.BorderGap().cx,mx.BorderGap().cy);
  265.  
  266.     CBrush brush, *pPrevBrush;
  267.     brush.CreateStockObject(NULL_BRUSH);
  268.     pPrevBrush = pDC->SelectObject(&brush);
  269.  
  270.     CFont& font      = pDC->IsPrinting() ? m_fontPrinter : m_fontScreen;
  271.     CFont *pPrevFont = pDC->SelectObject(&font);
  272.  
  273.     // Draw the text
  274.     pDC->DrawText(GetBannerText(), &(rcText+scroll), 0); 
  275.  
  276.     pDC->SelectObject(pPrevFont);
  277.  
  278.     CPen pen, *pPrevPen;
  279.     pen.CreatePen(PS_SOLID, mx.BorderThickness().cx, 0);
  280.     pPrevPen = pDC->SelectObject(&pen);
  281.  
  282.     // Draw the border
  283.     if(GetBorder())
  284.     {
  285.         rcText.OffsetRect(-mx.BorderGap().cx,-mx.BorderGap().cy);
  286.         pDC->Rectangle(&(rcText+scroll));
  287.     }
  288.  
  289.     pDC->SelectObject(pPrevPen);
  290.     pen.DeleteObject();
  291.  
  292.     pDC->SelectObject(pPrevBrush);
  293.     brush.DeleteObject();
  294. }
  295.  
  296. void CBannerView::DrawRuler(CDC *pDC, CSize& scroll, CBannerMetrics& mx)
  297. {
  298.     int nPrevROP2 = pDC->SetROP2(R2_NOTXORPEN);
  299.  
  300.     CPen pen, *pPrevPen;
  301.     pen.CreateStockObject(BLACK_PEN);
  302.     pPrevPen = pDC->SelectObject(&pen);
  303.  
  304.     CFont font, *pPrevFont;
  305.     font.CreateStockObject(SYSTEM_FONT);
  306.     pPrevFont = pDC->SelectObject(&font);
  307.     
  308.     TCHAR szInchNum[4];
  309.     POINT pt[2];
  310.     for(int nInchNum=1; nInchNum <= m_sizeViewScreen.cx/mx.Inch().cx; nInchNum++)
  311.     {
  312.         pt[0].x = nInchNum*mx.Inch().cx+scroll.cx;
  313.         pt[0].y = 0;
  314.         pt[1].x = pt[0].x;
  315.         pt[1].y = s_nRulerTickSize;
  316.         pDC->Polyline(pt,2);
  317.  
  318.         pt[0].x = pt[1].x-s_nRulerNumberSize;
  319.         pt[0].y = pt[0].y;
  320.         pt[1].x = pt[0].x+s_nRulerNumberSize;
  321.         pt[1].y = pt[0].y+s_nRulerNumberSize;
  322.         pDC->DrawText(_itow(nInchNum,szInchNum,10), -1, (LPRECT)pt, DT_RIGHT | DT_TOP);
  323.     }
  324.  
  325.     for(nInchNum=1; nInchNum <= m_sizeViewScreen.cy/mx.Inch().cy; nInchNum++)
  326.     {
  327.         pt[0].x = 0;
  328.         pt[0].y = nInchNum*mx.Inch().cy+scroll.cy;
  329.         pt[1].x = s_nRulerTickSize;
  330.         pt[1].y = pt[0].y;
  331.         pDC->Polyline(pt,2);
  332.  
  333.         pt[0].x = pt[0].x;
  334.         pt[0].y = pt[1].y-s_nRulerNumberSize;
  335.         pt[1].x = pt[0].x+s_nRulerNumberSize;
  336.         pt[1].y = pt[0].y+s_nRulerNumberSize;
  337.         pDC->DrawText(_itow(nInchNum,szInchNum,10), -1, (LPRECT)pt, DT_LEFT | DT_BOTTOM);
  338.     }
  339.     
  340.     pDC->SelectObject(pPrevFont);
  341.     font.DeleteObject();
  342.  
  343.     pDC->SelectObject(pPrevPen);
  344.     pen.DeleteObject();
  345.  
  346.     pDC->SetROP2(nPrevROP2);
  347. }
  348.  
  349. void CBannerView::DrawPageBreaks(CDC *pDC, CSize& scroll, CBannerMetrics& mx)
  350. {
  351.     int nPageNum;
  352.     POINT pt[2];
  353.  
  354.     CPen pen, *pPrevPen;
  355.     pen.CreatePen(PS_SOLID, 0, 0);
  356.     pPrevPen = pDC->SelectObject(&pen);
  357.  
  358.     CBrush brush, *pPrevBrush;
  359.     brush.CreateStockObject(NULL_BRUSH);
  360.     pPrevBrush = pDC->SelectObject(&brush);
  361.  
  362.     CRect rcArea = CRect(m_rcMarginsScreen.left, 
  363.                          m_rcMarginsScreen.top, 
  364.                          m_sizeViewScreen.cx-m_rcMarginsScreen.right, 
  365.                          m_sizeViewScreen.cy-m_rcMarginsScreen.bottom);
  366.     pDC->Rectangle(&(rcArea+scroll));
  367.  
  368.     for(nPageNum=1; nPageNum < m_sizePageCount.cx; nPageNum++)
  369.     {
  370.         pt[0].x = nPageNum*m_sizePageScreen.cx+scroll.cx;
  371.         pt[0].y = rcArea.top+scroll.cy;
  372.         pt[1].x = pt[0].x;
  373.         pt[1].y = rcArea.bottom+scroll.cy;
  374.         pDC->Polyline(pt,2);
  375.     }
  376.  
  377.     for(nPageNum=1; nPageNum < m_sizePageCount.cy; nPageNum++)
  378.     {
  379.         pt[0].x = rcArea.left+scroll.cx;
  380.         pt[0].y = nPageNum*m_sizePageScreen.cy+scroll.cy;
  381.         pt[1].x = rcArea.right+scroll.cx;
  382.         pt[1].y = pt[0].y;
  383.         pDC->Polyline(pt,2);
  384.     }
  385.  
  386.     pDC->SelectObject(pPrevPen);
  387.     pen.DeleteObject();
  388.  
  389.     pDC->SelectObject(pPrevBrush);
  390.     brush.DeleteObject();
  391. }
  392.  
  393.  
  394. /////////////////////////////////////////////////////////////////////////////
  395. // CBannerView scrolling
  396.  
  397. // Since we don't want the ruler to be scrolled (it always stays at top and left), we need
  398. // to implement our own OnScrollBy (same as CScrollView::OnScrollBy except we don't call ScrollWindowEx)
  399. BOOL CBannerView::OnScrollBy(CSize sizeScroll, BOOL bDoScroll)
  400. {
  401.     int xOrig, x;
  402.     int yOrig, y;
  403.  
  404.     // don't scroll if there is no valid scroll range (ie. no scroll bar)
  405.     CScrollBar* pBar;
  406.     DWORD dwStyle = GetStyle();
  407.     pBar = GetScrollBarCtrl(SB_VERT);
  408.     if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
  409.         (pBar == NULL && !(dwStyle & WS_VSCROLL)))
  410.     {
  411.         // vertical scroll bar not enabled
  412.         sizeScroll.cy = 0;
  413.     }
  414.     pBar = GetScrollBarCtrl(SB_HORZ);
  415.     if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
  416.         (pBar == NULL && !(dwStyle & WS_HSCROLL)))
  417.     {
  418.         // horizontal scroll bar not enabled
  419.         sizeScroll.cx = 0;
  420.     }
  421.  
  422.     // adjust current x position
  423.     xOrig = x = GetScrollPos(SB_HORZ);
  424.     int xMax = GetScrollLimit(SB_HORZ);
  425.     x += sizeScroll.cx;
  426.     if (x < 0)
  427.         x = 0;
  428.     else if (x > xMax)
  429.         x = xMax;
  430.  
  431.     // adjust current y position
  432.     yOrig = y = GetScrollPos(SB_VERT);
  433.     int yMax = GetScrollLimit(SB_VERT);
  434.     y += sizeScroll.cy;
  435.     if (y < 0)
  436.         y = 0;
  437.     else if (y > yMax)
  438.         y = yMax;
  439.  
  440.     // did anything change?
  441.     if (x == xOrig && y == yOrig)
  442.         return FALSE;
  443.  
  444.     if (bDoScroll)
  445.     {
  446.         InvalidateRect(NULL); // Instead of calling ScrollWindowEx
  447.  
  448.         if (x != xOrig)
  449.             SetScrollPos(SB_HORZ, x);
  450.         if (y != yOrig)
  451.             SetScrollPos(SB_VERT, y);
  452.     }
  453.     return TRUE;
  454. }
  455.  
  456.  
  457.  
  458. /////////////////////////////////////////////////////////////////////////////
  459. // CBannerView command handlers
  460.  
  461. void CBannerView::OnBannerText() 
  462. {
  463.     m_BannerDlg.DoModal(GetDC());
  464.     GetDocument()->UpdateAllViews(NULL);
  465. }
  466.  
  467.  
  468. void CBannerView::OnRuler() 
  469. {
  470.     m_bRuler = !m_bRuler;
  471.     InvalidateRect(NULL);
  472. }
  473.  
  474. void CBannerView::OnUpdateRuler(CCmdUI* pCmdUI) 
  475. {
  476.     if(pCmdUI->m_pMenu != NULL)
  477.         pCmdUI->m_pMenu->CheckMenuItem(ID_RULER, m_bRuler ? MF_CHECKED : MF_UNCHECKED);
  478. }
  479.  
  480. void CBannerView::OnPageBreaks() 
  481. {
  482.     m_bPageBreaks = !m_bPageBreaks;
  483.     InvalidateRect(NULL);
  484. }
  485.  
  486. void CBannerView::OnUpdatePageBreaks(CCmdUI* pCmdUI) 
  487. {
  488.     if(pCmdUI->m_pMenu != NULL)
  489.         pCmdUI->m_pMenu->CheckMenuItem(ID_PAGES, m_bPageBreaks ? MF_CHECKED : MF_UNCHECKED);
  490. }
  491.  
  492. int CBannerView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  493. {
  494.     if (CScrollView::OnCreate(lpCreateStruct) == -1)
  495.         return -1;
  496.  
  497.     // CZoomList::Initialize() calls GetActiveView(), so we need to set the active view.
  498.     GetParentFrame()->SetActiveView(this); 
  499.     return 0;
  500. }
  501.  
  502.  
  503.  
  504. /////////////////////////////////////////////////////////////////////////////
  505. // CBannerView printing
  506.  
  507. // Superfunction of CPrintDialog::DoModal
  508. BOOL CBannerView::OnPreparePrinting(CPrintInfo* pInfo)
  509. {
  510.     CPrintDialog *pPD = pInfo->m_pPD;
  511.  
  512.     // Turn off print range selection.
  513.     pPD->m_pd.dwFlags |= PD_DISABLEPRINTRANGE;
  514.  
  515.     // Pass in margins
  516.     pPD->m_pd.dwFlags |= PD_MARGINS | PD_INTHOUSANDTHSOFINCHES;
  517.     memcpy(&pPD->m_pd.rcMargin, &m_rcMarginsPrintDlg, sizeof(RECT));
  518.  
  519.     // Set portrait/landscape
  520.     pPD->m_pd.dwFlags |= (m_sizePagePrinter.cy > m_sizePagePrinter.cx) ?
  521.         PD_SELECTPORTRAIT : PD_SELECTLANDSCAPE;
  522.  
  523.     // Call print dialog box (and whatever else is done in DoPreparePrinting).
  524.     BOOL bResult = DoPreparePrinting(pInfo);
  525.         
  526.     // Get new margins, converting if necessary 
  527.     // Note: we could have called CPrintDialog::GetMargins() here.
  528.     memcpy(&m_rcMarginsPrintDlg, &pPD->m_pd.rcMargin, sizeof(RECT));
  529.     if(pPD->m_pd.dwFlags & PD_INHUNDREDTHSOFMILLIMETERS)
  530.     {
  531.         // convert to 1000ths of inches (divide by 2.54)
  532.         m_rcMarginsPrinter.left   = (int)(m_rcMarginsPrinter.left   * 100 / 254);
  533.         m_rcMarginsPrinter.right  = (int)(m_rcMarginsPrinter.right  * 100 / 254);
  534.         m_rcMarginsPrinter.top    = (int)(m_rcMarginsPrinter.top    * 100 / 254);
  535.         m_rcMarginsPrinter.bottom = (int)(m_rcMarginsPrinter.bottom * 100 / 254);
  536.     }
  537.     InvalidateRect(NULL); // repaint window because the printer settings may have changed
  538.  
  539.     return bResult;
  540. }
  541.  
  542. // Gets called after the print dialog box but before the first page.
  543. // We are responsible for setting information in CPrintInfo
  544. void CBannerView::OnBeginPrinting(CDC* pPrinterDC, CPrintInfo* pInfo)
  545. {
  546.     ComputeSizes (pPrinterDC);
  547.     
  548.     pInfo->SetMinPage(1);
  549.     pInfo->SetMaxPage(m_sizePageCount.cx * m_sizePageCount.cy);
  550.  
  551.     BOOL bResult = CreateBannerFont(pPrinterDC, &m_fontPrinter);
  552.     if(!bResult)
  553.     {
  554.         AfxMessageBox(CString((LPCTSTR)IDS_MESSAGE3));
  555.         pInfo->m_bContinuePrinting = FALSE;
  556.     }
  557. }
  558.  
  559. // Gets called at the beginning of each page (for both screen drawing and printing).  
  560. // If the number of pages had not been set in OnBeginPrinting, we're supposed to
  561. // set m_bContinuePrinting to FALSE.  For this sample, nothing needs to be done here. 
  562. void CBannerView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
  563. {
  564. }
  565.  
  566. // Gets called to print a page
  567. void CBannerView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
  568. {
  569.     CSize page((pInfo->m_nCurPage-1) % m_sizePageCount.cx,
  570.                (pInfo->m_nCurPage-1) / m_sizePageCount.cx);
  571.  
  572.     CSize scroll(-page.cx*m_sizePagePrinter.cx, -page.cy*m_sizePagePrinter.cy);
  573.     CBannerMetrics mx(pDC);
  574.  
  575.     if(m_fontPrinter.m_hObject != NULL)
  576.         DrawBanner(pDC, scroll, mx);
  577. }
  578.  
  579. // Gets called at the end of a print job.
  580. void CBannerView::OnEndPrinting(CDC*pDC, CPrintInfo* pInfo)
  581. {
  582.     if(m_fontPrinter.m_hObject != NULL)
  583.         m_fontPrinter.DeleteObject();
  584. }
  585.  
  586. void CBannerView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  587. {
  588.     int nMapMode;
  589.     CSize sizeTotal, sizePage, sizeLine;
  590.     GetDeviceScrollSizes(nMapMode, sizeTotal, sizePage, sizeLine);
  591.  
  592.     if(nChar == VK_UP)
  593.         OnScrollBy(CSize(0,-sizeLine.cy));
  594.     else if(nChar == VK_DOWN)
  595.         OnScrollBy(CSize(0,sizeLine.cy));
  596.     else if(nChar == VK_LEFT)
  597.         OnScrollBy(CSize(-sizeLine.cx,0));
  598.     else if(nChar == VK_RIGHT)
  599.         OnScrollBy(CSize(sizeLine.cx,0));
  600.     else
  601.         CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
  602. }
  603.